home *** CD-ROM | disk | FTP | other *** search
/ PC/CD Gamer UK 120 / CD Gamer Issue 120 (March 2003) (Disc 2).ISO / mods / Q2_Codered / codeRED1_0.exe / Data1.cab / M_martian.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-12-28  |  15.3 KB  |  592 lines

  1. /*
  2. ==============================================================================
  3.  
  4. Martian Soldiers
  5.  
  6. ==============================================================================
  7. */
  8.  
  9. #include "g_local.h"
  10. #include "m_player.h"
  11.    
  12.  
  13. static int sound_pain;
  14. static int sound_die;
  15. static int sound_idle;
  16. static int sound_punch;
  17. static int sound_sight;
  18. static int sound_search;
  19. static int sound_shoot;
  20. static int sound_glass;
  21.  
  22.  
  23. void martian_search (edict_t *self)
  24. {
  25.     gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0);
  26. }
  27.  
  28. mframe_t martian_frames_stand [] =
  29. {
  30.     ai_stand, 0, NULL,
  31.     ai_stand, 0, NULL,
  32.     ai_stand, 0, NULL,
  33.     ai_stand, 0, NULL,
  34.     ai_stand, 0, NULL,
  35.     ai_stand, 0, NULL,
  36.     ai_stand, 0, NULL,
  37.     ai_stand, 0, NULL,
  38.     ai_stand, 0, NULL,
  39.     ai_stand, 0, NULL,
  40.     ai_stand, 0, NULL,
  41.     ai_stand, 0, NULL,
  42.     ai_stand, 0, NULL,
  43.     ai_stand, 0, NULL,
  44.     ai_stand, 0, NULL,
  45.     ai_stand, 0, NULL,
  46.     ai_stand, 0, NULL,
  47.     ai_stand, 0, NULL,
  48.     ai_stand, 0, NULL,
  49.     ai_stand, 0, NULL,
  50.     ai_stand, 0, NULL,
  51.     ai_stand, 0, NULL,
  52.     ai_stand, 0, NULL,
  53.     ai_stand, 0, NULL,
  54.     ai_stand, 0, NULL,
  55.     ai_stand, 0, NULL,
  56.     ai_stand, 0, NULL,
  57.     ai_stand, 0, NULL,
  58.     ai_stand, 0, NULL,
  59.     ai_stand, 0, NULL,
  60.     ai_stand, 0, NULL,
  61.     ai_stand, 0, NULL,
  62.     ai_stand, 0, NULL,
  63.     ai_stand, 0, NULL,
  64.     ai_stand, 0, NULL,
  65.     ai_stand, 0, NULL,
  66.     ai_stand, 0, NULL,
  67.     ai_stand, 0, NULL,
  68.     ai_stand, 0, NULL,
  69.     ai_stand, 0, NULL
  70.     
  71. };
  72. mmove_t martian_move_stand = {FRAME_stand01, FRAME_stand40, martian_frames_stand, NULL};
  73.  
  74. void martian_stand (edict_t *self)
  75. {
  76.     self->monsterinfo.currentmove = &martian_move_stand;
  77. }
  78.  
  79. mframe_t martian_frames_run1 [] =
  80. {
  81.     ai_run, 25, NULL,
  82.     ai_run, 10, NULL,
  83.     ai_run, 5, NULL,
  84.     ai_run, 24, NULL,
  85.     ai_run, 11, NULL,
  86.     ai_run, 5, NULL
  87. };
  88. mmove_t martian_move_run1 = {FRAME_run1, FRAME_run6, martian_frames_run1, NULL};
  89.  
  90. void martian_run (edict_t *self)
  91. {
  92.     if (self->monsterinfo.aiflags & AI_STAND_GROUND)
  93.         self->monsterinfo.currentmove = &martian_move_stand;
  94.     else
  95.         self->monsterinfo.currentmove = &martian_move_run1;
  96. }
  97. mframe_t martian_frames_wave [] =
  98. {
  99.     ai_stand, 0, NULL,
  100.     ai_stand, 0, NULL,
  101.     ai_stand, 0, NULL,
  102.     ai_stand, 0, NULL,
  103.     ai_stand, 0, NULL,
  104.     ai_stand, 0, NULL,
  105.     ai_stand, 0, NULL,
  106.     ai_stand, 0, NULL,
  107.     ai_stand, 0, NULL,
  108.     ai_stand, 0, NULL,
  109.     ai_stand, 0, NULL
  110. };
  111.     
  112. mmove_t martian_move_wave = {FRAME_wave01, FRAME_wave11, martian_frames_wave, martian_run};
  113.  
  114. mframe_t martian_frames_point [] =
  115. {
  116.     ai_stand, 0, NULL,
  117.     ai_stand, 0, NULL,
  118.     ai_stand, 0, NULL,
  119.     ai_stand, 0, NULL,
  120.     ai_stand, 0, NULL,
  121.     ai_stand, 0, NULL,
  122.     ai_stand, 0, NULL,
  123.     ai_stand, 0, NULL,
  124.     ai_stand, 0, NULL,
  125.     ai_stand, 0, NULL,
  126.     ai_stand, 0, NULL,
  127.     ai_stand, 0, NULL
  128. };
  129.     
  130. mmove_t martian_move_point = {FRAME_point01, FRAME_point12, martian_frames_point, martian_run};
  131.  
  132. mframe_t martian_frames_flip [] =
  133. {
  134.     ai_stand, 0, NULL,
  135.     ai_stand, 0, NULL,
  136.     ai_stand, 0, NULL,
  137.     ai_stand, 0, NULL,
  138.     ai_stand, 0, NULL,
  139.     ai_stand, 0, NULL,
  140.     ai_stand, 0, NULL,
  141.     ai_stand, 0, NULL,
  142.     ai_stand, 0, NULL,
  143.     ai_stand, 0, NULL,
  144.     ai_stand, 0, NULL,
  145.     ai_stand, 0, NULL
  146. };
  147.     
  148. mmove_t martian_move_flip = {FRAME_flip01, FRAME_flip12, martian_frames_flip, martian_run};
  149.  
  150. mframe_t martian_frames_taunt [] =
  151. {
  152.     ai_stand, 0, NULL,
  153.     ai_stand, 0, NULL,
  154.     ai_stand, 0, NULL,
  155.     ai_stand, 0, NULL,
  156.     ai_stand, 0, NULL,
  157.     ai_stand, 0, NULL,
  158.     ai_stand, 0, NULL,
  159.     ai_stand, 0, NULL,
  160.     ai_stand, 0, NULL,
  161.     ai_stand, 0, NULL,
  162.     ai_stand, 0, NULL,
  163.     ai_stand, 0, NULL,
  164.     ai_stand, 0, NULL,
  165.     ai_stand, 0, NULL,
  166.     ai_stand, 0, NULL,
  167.     ai_stand, 0, NULL,
  168.     ai_stand, 0, NULL
  169. };
  170.     
  171. mmove_t martian_move_taunt = {FRAME_taunt01, FRAME_taunt17, martian_frames_taunt, martian_run};
  172.  
  173. void martian_run_after_shoot (edict_t *self)
  174. {
  175.     if (random() < 0.8)
  176.         self->monsterinfo.currentmove = &martian_move_run1;
  177.     else
  178.     {
  179.         if(random() < 0.5)
  180.             self->monsterinfo.currentmove = &martian_move_flip;
  181.         else 
  182.             self->monsterinfo.currentmove = &martian_move_taunt;
  183.     }
  184. }
  185.  
  186. void MartianShot (edict_t *self)
  187. {
  188.     vec3_t    forward, right;
  189.     vec3_t    start;
  190.     vec3_t    end;
  191.     vec3_t    dir;
  192.     vec3_t    from;
  193.     int        damage = 15;
  194.     int        flash_number = MZ2_MAKRON_BFG;
  195.     trace_t tr;
  196.     
  197.     if (self->spawnflags & 1)
  198.         damage = 20;
  199.  
  200.     AngleVectors (self->s.angles, forward, right, NULL);
  201.     G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start);
  202.     VectorCopy (self->s.origin, start);
  203.  
  204.     start[2] = start[2] + 26;
  205.     VectorCopy (self->enemy->s.origin, end);
  206.     end[2] += self->enemy->viewheight;
  207.     VectorSubtract (end, start, dir);
  208.     
  209.     right[0] = right[0] * 8;
  210.     right[1] = right[1] * 8;
  211.     
  212.     VectorAdd(start, right, start);
  213.     end[2] = end[2] - 32;
  214.  
  215.     VectorCopy (start, from);
  216.     tr = gi.trace (from, NULL, NULL, end, self, MASK_SHOT);      
  217.     VectorCopy (tr.endpos, from);
  218.  
  219.     if (self->spawnflags & 1)
  220.     {
  221.         gi.WriteByte (svc_temp_entity);
  222.         gi.WriteByte (TE_RAILTRAIL);
  223.         gi.WritePosition (start);
  224.         gi.WritePosition (end);
  225.         gi.multicast (start, MULTICAST_PHS); 
  226.         gi.WriteByte (svc_temp_entity);
  227.         gi.WriteByte (TE_MEDIC_CABLE_ATTACK);
  228.         gi.WritePosition (start);
  229.         gi.WritePosition (end);
  230.         gi.multicast (start, MULTICAST_PHS); 
  231.         gi.sound (self, CHAN_VOICE, sound_punch, 1, ATTN_NORM, 0);
  232.     }
  233.     else
  234.     {
  235.  
  236.         gi.WriteByte (svc_temp_entity);
  237.         gi.WriteByte (TE_SHOTGUN);
  238.         gi.WritePosition (start);
  239.         gi.WritePosition (end);
  240.         gi.multicast (start, MULTICAST_PHS); 
  241.         gi.sound (self, CHAN_VOICE, sound_shoot, 1, ATTN_NORM, 0);
  242.     }
  243.     
  244.     if ((tr.ent != self) && (tr.ent->takedamage))
  245.         T_Damage (tr.ent, self, self, dir, tr.endpos, tr.plane.normal, damage, 0, 0, MOD_HYPERBLASTER);
  246.     else if (!((tr.surface) && (tr.surface->flags & SURF_SKY)))
  247.     {  
  248.         gi.WriteByte (svc_temp_entity);
  249.         gi.WriteByte (TE_SCREEN_SPARKS);
  250.         gi.WritePosition (tr.endpos);
  251.         gi.WriteDir (tr.plane.normal);
  252.         gi.multicast (self->s.origin, MULTICAST_PVS);
  253.     }
  254. }
  255.  
  256. mframe_t martian_frames_attack_shoot [] =
  257. {
  258.         ai_charge, 0, NULL,
  259.         ai_charge, 0, MartianShot,
  260.         ai_charge, 0, NULL,
  261.         ai_charge, 0, NULL,
  262.         ai_charge, 0, NULL,
  263.         ai_charge, 0, NULL,
  264.         ai_charge, 0, NULL,
  265.         ai_charge, 0, NULL
  266. };
  267. mmove_t martian_move_attack_shoot = {FRAME_attack1, FRAME_attack8, martian_frames_attack_shoot, martian_run_after_shoot};
  268.  
  269.  
  270. void martian_sight (edict_t *self, edict_t *other)
  271. {
  272.     gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
  273.     if(random() < 0.5)
  274.         self->monsterinfo.currentmove = &martian_move_wave;
  275.     else
  276.         self->monsterinfo.currentmove = &martian_move_point;
  277. }
  278.  
  279. void martian_melee (edict_t *self)
  280. {
  281.     self->monsterinfo.currentmove = &martian_move_attack_shoot;
  282. }
  283.  
  284. void martian_attack (edict_t *self)
  285. {
  286.     
  287.     if(random() > 0.5)
  288.         self->monsterinfo.currentmove = &martian_move_point;
  289.     else 
  290.         self->monsterinfo.currentmove = &martian_move_attack_shoot;
  291. }
  292.  
  293. void martian_duck_down (edict_t *self)
  294. {
  295.     if (self->monsterinfo.aiflags & AI_DUCKED)
  296.         return;
  297.     self->monsterinfo.aiflags |= AI_DUCKED;
  298.     
  299.  
  300.     self->maxs[2] -= 32;
  301.     self->takedamage = DAMAGE_YES;
  302.     self->monsterinfo.pausetime = level.time + 1;
  303.     gi.linkentity (self);
  304. }
  305.  
  306. void martian_duck_hold (edict_t *self)
  307. {
  308.     if (level.time >= self->monsterinfo.pausetime)
  309.         self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
  310.     else
  311.         self->monsterinfo.aiflags |= AI_HOLD_FRAME;
  312. }
  313.  
  314. void martian_duck_up (edict_t *self)
  315. {
  316.     self->monsterinfo.aiflags &= ~AI_DUCKED;
  317.     self->maxs[2] += 32;
  318.     self->takedamage = DAMAGE_AIM;
  319.     gi.linkentity (self);
  320. }
  321.  
  322. mframe_t martian_frames_duck [] =
  323. {
  324.     ai_move, 0,  martian_duck_down,
  325.     ai_move, 0,  NULL,
  326.     ai_move, 0,  NULL,
  327.     ai_move, 0,  martian_duck_hold,
  328.     ai_move, 0,  NULL,
  329.     ai_move, 0, NULL,
  330.     ai_move, 0,  martian_duck_up,
  331.     ai_move, 0, NULL
  332. };
  333. mmove_t    martian_move_duck = {FRAME_duck01, FRAME_duck08, martian_frames_duck, martian_run};
  334.  
  335. void martian_dodge (edict_t *self, edict_t *attacker, float eta)
  336. {
  337.     if (random() > 0.25)
  338.         return;
  339.  
  340.     if (!self->enemy)
  341.         self->enemy = attacker;
  342.  
  343.     self->monsterinfo.currentmove = &martian_move_duck;
  344. }
  345.  
  346. mframe_t martian_frames_pain1 [] =
  347. {
  348.     
  349.     ai_move, 0, NULL,
  350.     ai_move, 0, NULL,
  351.     ai_move, 0, NULL,
  352.     ai_move, 0, NULL
  353. };
  354. mmove_t martian_move_pain1 = {FRAME_pain101, FRAME_pain104, martian_frames_pain1, martian_run};
  355.  
  356.  
  357. mframe_t martian_frames_pain2 [] =
  358. {
  359.     ai_move, 0, NULL,
  360.     ai_move, 0, NULL,
  361.     ai_move, 0, NULL,
  362.     ai_move, 0, NULL
  363. };
  364. mmove_t martian_move_pain2 = {FRAME_pain201, FRAME_pain204, martian_frames_pain2, martian_run};
  365.  
  366. mframe_t martian_frames_pain3 [] =
  367. {
  368.     ai_move, 0, NULL,
  369.     ai_move, 0, NULL,
  370.     ai_move, 0, NULL,
  371.     ai_move, 0, NULL
  372. };
  373. mmove_t martian_move_pain3 = {FRAME_pain301, FRAME_pain304, martian_frames_pain3, martian_run};
  374.  
  375. void martian_pain (edict_t *self, edict_t *other, float kick, int damage)
  376. {
  377.     float spd;
  378.     vec3_t    org;
  379.  
  380.     if (level.time < self->pain_debounce_time)
  381.         return;
  382.  
  383.     self->pain_debounce_time = level.time + 3;
  384.  
  385.     if ((self->health < (self->max_health / 2)) && (self->s.skinnum == 0))
  386.     {
  387.         //break the helmet, and put green blood on the martian
  388.         // a bunch of little chunks
  389.         gi.sound (self, CHAN_VOICE, sound_glass, 1, ATTN_NORM, 0);
  390.         spd = 1.5;
  391.         org[0] = self->s.origin[0] + crandom() * 5.0;
  392.         org[1] = self->s.origin[1] + crandom() * 5.0;
  393.         org[2] = self->s.origin[2] + crandom() * 5.0;
  394.         ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org);
  395.         org[0] = self->s.origin[0] + crandom() * 5.0;
  396.         org[1] = self->s.origin[1] + crandom() * 5.0;
  397.         org[2] = self->s.origin[2] + crandom() * 5.0;
  398.         ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org);
  399.         org[0] = self->s.origin[0] + crandom() * 5.0;
  400.         org[1] = self->s.origin[1] + crandom() * 5.0;
  401.         org[2] = self->s.origin[2] + crandom() * 5.0;
  402.         ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org);
  403.         org[0] = self->s.origin[0] + crandom() * 5.0;
  404.         org[1] = self->s.origin[1] + crandom() * 5.0;
  405.         org[2] = self->s.origin[2] + crandom() * 5.0;
  406.         ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org);
  407.         org[0] = self->s.origin[0] + crandom() * 5.0;
  408.         org[1] = self->s.origin[1] + crandom() * 5.0;
  409.         org[2] = self->s.origin[2] + crandom() * 5.0;
  410.         ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org);
  411.         org[0] = self->s.origin[0] + crandom() * 5.0;
  412.         org[1] = self->s.origin[1] + crandom() * 5.0;
  413.         org[2] = self->s.origin[2] + crandom() * 5.0;
  414.         ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org);
  415.         org[0] = self->s.origin[0] + crandom() * 5.0;
  416.         org[1] = self->s.origin[1] + crandom() * 5.0;
  417.         org[2] = self->s.origin[2] + crandom() * 5.0;
  418.         ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org);
  419.         org[0] = self->s.origin[0] + crandom() * 5.0;
  420.         org[1] = self->s.origin[1] + crandom() * 5.0;
  421.         org[2] = self->s.origin[2] + crandom() * 5.0;
  422.         ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org);
  423.         org[0] = self->s.origin[0] + crandom() * 5.0;
  424.         org[1] = self->s.origin[1] + crandom() * 5.0;
  425.         org[2] = self->s.origin[2] + crandom() * 5.0;
  426.         ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org);
  427.         self->s.modelindex2 = 0;
  428.         self->s.skinnum = 1;
  429.         
  430.         if(random() < 0.3)
  431.             self->monsterinfo.currentmove = &martian_move_pain1;
  432.         else if(random() < 0.5)
  433.             self->monsterinfo.currentmove = &martian_move_pain2;
  434.         else
  435.             self->monsterinfo.currentmove = &martian_move_pain3;
  436.     }
  437.     else
  438.     {
  439.         gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0);
  440.  
  441.         if(random() < 0.3)
  442.             self->monsterinfo.currentmove = &martian_move_pain1;
  443.         else if(random() < 0.5)
  444.             self->monsterinfo.currentmove = &martian_move_pain2;
  445.         else
  446.             self->monsterinfo.currentmove = &martian_move_pain3;
  447.     }
  448. }
  449.  
  450.  
  451. void martian_dead (edict_t *self)
  452. {
  453.     VectorSet (self->mins, -16, -16, 0);
  454.     VectorSet (self->maxs, 16, 16, 16);
  455.     self->movetype = MOVETYPE_TOSS;
  456.     self->svflags |= SVF_DEADMONSTER;
  457.     self->nextthink = 0;
  458.     gi.linkentity (self);
  459. }
  460.  
  461.  
  462. mframe_t martian_frames_death1 [] =
  463. {
  464.  
  465.     ai_move, 0, NULL,
  466.     ai_move, 0, NULL,
  467.     ai_move, 0, NULL,
  468.     ai_move, 0, NULL,
  469.     ai_move, 0, NULL,
  470.     ai_move, 0, NULL
  471.     
  472. };
  473. mmove_t martian_move_death1 = {FRAME_death101, FRAME_death106, martian_frames_death1, martian_dead};
  474.  
  475.  
  476. mframe_t martian_frames_death2 [] =
  477. {
  478.  
  479.     ai_move, 0, NULL,
  480.     ai_move, 0, NULL,
  481.     ai_move, 0, NULL,
  482.     ai_move, 0, NULL,
  483.     ai_move, 0, NULL,
  484.     ai_move, 0, NULL
  485. };
  486. mmove_t martian_move_death2 = {FRAME_death201, FRAME_death206, martian_frames_death2, martian_dead};
  487.  
  488. mframe_t martian_frames_death3 [] =
  489. {
  490.  
  491.     ai_move, 0, NULL,
  492.     ai_move, 0, NULL,
  493.     ai_move, 0, NULL,
  494.     ai_move, 0, NULL,
  495.     ai_move, 0, NULL,
  496.     ai_move, 0, NULL,
  497.     ai_move, 0, NULL
  498. };
  499. mmove_t martian_move_death3 = {FRAME_death301, FRAME_death307, martian_frames_death3, martian_dead};
  500.  
  501. void martian_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
  502. {
  503.     int        n;
  504.     
  505.     if (self->health <= self->gib_health)
  506.     {
  507.         gi.sound (self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0);
  508.         self->s.modelindex3 = 0;
  509.         for (n = 0; n < 8; n++)
  510.             ThrowGib (self, "models/objects/gibs/mart_gut/tris.md2", damage, GIB_ORGANIC, EF_GREENGIB);
  511.  
  512.         ThrowHead (self, "models/objects/gibs/mart_gut/tris.md2", damage, GIB_ORGANIC, EF_GREENGIB);
  513.         self->deadflag = DEAD_DEAD;
  514.         return;
  515.     }
  516.  
  517.     if (self->deadflag == DEAD_DEAD)
  518.         return;
  519.  
  520.     gi.sound (self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0);
  521.     self->deadflag = DEAD_DEAD;
  522.     self->takedamage = DAMAGE_YES;
  523.     self->s.modelindex2 = 0;  //get rid of helmet.
  524.     if(random() < 0.3)
  525.         self->monsterinfo.currentmove = &martian_move_death1;
  526.     else if(random() < 0.5)
  527.         self->monsterinfo.currentmove = &martian_move_death2;
  528.     else
  529.         self->monsterinfo.currentmove = &martian_move_death3;
  530. }
  531.  
  532.  
  533. /*QUAKED monster_martian (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
  534. */
  535. void SP_monster_martian (edict_t *self)
  536. {
  537.     if (deathmatch->value)
  538.     {
  539.         G_FreeEdict (self);
  540.         return;
  541.     }
  542.  
  543.     // pre-caches
  544.     sound_pain  = gi.soundindex ("martian/ack2.wav");
  545.     sound_die   = gi.soundindex ("martian/death.wav");
  546.     sound_idle  = gi.soundindex ("martian/ack1.wav");
  547.     sound_punch = gi.soundindex ("martian/laser.wav");
  548.     sound_search = gi.soundindex ("martian/ack1.wav");
  549.     sound_sight = gi.soundindex ("martian/ack1.wav");
  550.     sound_shoot = gi.soundindex ("martian/blaster.wav");
  551.     sound_glass = gi.soundindex ("martian/glasbk.wav");
  552.  
  553.     if(self->spawnflags & 1)
  554.         self->s.modelindex = gi.modelindex("models/monsters/hi_res/martian_assassin/tris.md2");
  555.     else
  556.         self->s.modelindex = gi.modelindex("models/monsters/hi_res/martian/tris.md2");
  557.     
  558.     self->s.modelindex2 = gi.modelindex("models/monsters/hi_res/martian_helmet/tris.md2");
  559.  
  560.     self->s.modelindex3 = gi.modelindex("models/monsters/martian_weapon/tris.md2");
  561.  
  562.     VectorSet (self->mins, -16, -16, 0);
  563.     VectorSet (self->maxs, 16, 16, 64);
  564.     self->movetype = MOVETYPE_STEP;
  565.     self->solid = SOLID_BBOX;
  566.  
  567.     self->classname = "monster_martian";
  568.  
  569.     self->max_health = 150;
  570.     self->health = self->max_health;
  571.     self->gib_health = -40;
  572.     self->mass = 150;
  573.  
  574.     self->pain = martian_pain;
  575.     self->die = martian_die;
  576.     self->monsterinfo.stand = martian_stand;
  577.     self->monsterinfo.walk = martian_run;
  578.     self->monsterinfo.run = martian_run;
  579.     self->monsterinfo.dodge = martian_dodge;
  580.     self->monsterinfo.attack = martian_attack;
  581.     self->monsterinfo.melee = martian_melee;
  582.     self->monsterinfo.sight = martian_sight;
  583.     self->monsterinfo.search = martian_search;
  584.  
  585.     self->monsterinfo.currentmove = &martian_move_stand;
  586.     self->monsterinfo.scale = MODEL_SCALE;
  587.  
  588.     gi.linkentity (self);
  589.  
  590.     walkmonster_start (self);
  591. }
  592.